import { Component, useEffect, useState } from "react";
import reactLogo from "./assets/react.svg";

const API = process.env.BACKEND_API;

type PresignedUrlResponse = {
	signed_url: string;
};

async function fetchPresignedUrl(fileName: string): Promise<string> {
	// 假设后端提供了一个接口来获取预签名 URL
	const response = await fetch(`${API}/generate_presigned_url?object_key=${fileName}`);
	if (!response.ok) {
		throw new Error("Failed to fetch presigned URL");
	}
	const data: PresignedUrlResponse = await response.json();
	console.log(data)
	return data.signed_url;
}

async function uploadText(text: string) {
	// 使用 Fetch API 上传文件
	const url = new URL('/upload_text', API);
	const uploadResponse = await fetch(url, {
		method: "POST",
		body: text,
		headers: {
			"Content-Type": "text/plain",
		},
	});
	const key = await uploadResponse.text();
	if (uploadResponse.ok) {
		alert(`Upload successfully, Key: ${key}`);
	} else {
		alert(`Failed to upload file: ${uploadResponse.statusText}`);
	}
}

async function uploadFile(file: File) {
	if (!file) {
		alert("Please select a file first!");
		return;
	}

	try {
		// 获取预签名 URL
		const signedUrl = await fetchPresignedUrl(file.name);

		// 使用 Fetch API 上传文件
		const uploadResponse = await fetch(signedUrl, {
			method: "PUT",
			body: file,
			headers: {
				"Content-Type": file.type,
			},
		});

		if (!uploadResponse.ok) {
			alert(`Failed to upload file: ${uploadResponse.statusText}`);
			return
		}

		const url = new URL('/upload_file', API);
		const uploadResponse2 = await fetch(url, {
			method: "POST",
			body: file.name,
			headers: {
				"Content-Type": "text/plain",
			},
		});
		if (!uploadResponse2.ok) {
			alert(`Failed to upload file: ${uploadResponse2.statusText}`);
		}
		const key = await uploadResponse2.text()
		alert(`Upload successfully, Key: ${key}`);

	} catch (error) {
		console.error("Error uploading file:", error);
		alert("An error occurred while uploading the file.");
	}
}

async function getContent(key: string) {
	const url = new URL("/download?query=" + key, API);
	const res = await fetch(url);
	const data = await res.json();

	console.log(data)
	if (data["ty"] === "file") {
		return { type: "url", signed_url: data.signed_url, filename: data.filename };
	} else if (data["ty"] === "text") {
		return { type: "text", content: data.content };
	} else {
		return { type: "error" };
	}
}

function Upload() {
	const [f, setFile] = useState<File>();
	const [t, setText] = useState<string>("");
	const [isFile, setIsFile] = useState(false);

	const Warning = () => {
		if (isFile && f && f.size > 1024 * 1024 * 100) {
			const mb_fsize = f.size / (1024 * 1024)
			if (mb_fsize > 1024) {
				const GB = parseFloat((mb_fsize / 1024).toPrecision(2))
				return <p>文件大小为{GB}GB，假设您的网速为10MB/s，需要花费{Math.round(mb_fsize / 10)}秒，请耐心等待</p>
			}
			const MB = parseFloat(mb_fsize.toPrecision(2))
			return <p>文件大小为{MB}MB，假设您的网速为10MB/s，需要花费{Math.round(MB / 10)}秒，请耐心等待</p>
		}
		return <></>
	}

	return (
		<div>
			<h2>Upload</h2>
			<div>
				<strong>mode: {isFile ? "file" : "text"}   </strong>
				<button onClick={() => {
					setIsFile(!isFile);
					setFile(undefined);
					setText("");
				}}>switch</button>
			</div>
			<div>
				{
					isFile ? <input type="file" onChange={(e) => {
						console.log(e.target.files);
						setFile(e.target.files ? e.target.files[0] : undefined);
						setText(e.target.files ? e.target.files[0].name : "");
					}} /> :
						<textarea
							value={t}
							onChange={(e) => {
								setText(e.target.value)
							}}
							rows={10}
							cols={50}
							placeholder="Type your text here..."
						/>
				}
			</div>
			<button onClick={() => {
				if (isFile) {
					uploadFile(f as File);
				} else {
					const encoded = encodeURIComponent(t);
					uploadText(encoded);
				}
			}}>Upload</button>
			<Warning />
		</div>
	);
}

import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
import { a11yDark } from "react-syntax-highlighter/dist/esm/styles/prism";

const CodeViewer = ({ code }: { code: string }) => {
	return (
		<div className="code-container">
			<SyntaxHighlighter language="text" style={a11yDark}>
				{code}
			</SyntaxHighlighter>
		</div>
	);
};

function Download() {
	const [count, setCount] = useState<string>("");
	const [content, setContent] = useState<JSX.Element>();

	return (
		<>
			<h2>Download</h2>
			<div>
				<input type="text" placeholder="Key" value={count} onChange={(e) => {
					setCount(e.target.value)
				}} />
				<button type="button" onClick={() => {
					getContent(count).then((data) => {
						switch (data.type) {
							case "error":
								setContent(<p>{count}不存在</p>);
								return;
							case "url":
								setContent(<>
									<p>File: {data.filename}</p>
									<button type="button" onClick={() => {
										const a = document.createElement("a");
										a.href = data.signed_url;
										a.download = data.filename;
										document.body.appendChild(a);
										a.click();
									}}>click to download</button>
								</>);
								return;
							case "text":
								const decoded = decodeURIComponent(data.content);
								setContent(<CodeViewer code={decoded} />);
								return;
						}
					})
				}}>check</button>
			</div>

			<center>{content}</center>
		</>
	);
}

function App() {
	const [showUpload, setShowUpload] = useState(false);

	useEffect(() => {
		console.log(process.env.BACKEND_API)
	}, [])

	return (
		<div className="App">
			<div>
				<a href="#" onClick={() => setShowUpload(!showUpload)}>
					<img src={reactLogo} className="logo react" alt="React logo" />
				</a>
			</div>
			{showUpload ? <Upload /> : <Download />}
		</div>
	);
}

export default App;
